Add more info to FAQ about deps#1815
Conversation
| } | ||
|
|
||
| useEffect(() => { | ||
| function handleStatusChange(status) { |
There was a problem hiding this comment.
I moved these since it's harder to tell when it's safe, and we should probably just teach people to put them inside effects as a default.
There was a problem hiding this comment.
I agree. Functions are generally only called within the effect, so prefer to teach this as the default. As a result a value and not a function will be the effect's dependency, which is slightly easier to understand for beginners.
|
Deploy preview for reactjs ready! Built with commit 7639a38 |
content/docs/hooks-faq.md
Outdated
|
|
||
| ### Why am I seeing stale props or state inside my function? {#why-am-i-seeing-stale-props-or-state-inside-my-function} | ||
|
|
||
| Any function inside a component, including event handlers and effects, “sees” the props and state from the render it was defined in. For example, consider code like this: |
There was a problem hiding this comment.
A few suggestions.
- "sees" is clear enough for me, but due to the quotes maybe a little imprecise.
- Functions are defined once, but are potentially created multiple times (during renders).
| Any function inside a component, including event handlers and effects, “sees” the props and state from the render it was defined in. For example, consider code like this: | |
| Any function inside a component, including event handlers and effects, contain ("sees") the props and state from the render it was created in. For example, consider code like this: |
sophiebits
left a comment
There was a problem hiding this comment.
a couple comments, will review again later…
content/docs/hooks-effect.md
Outdated
| >If you pass an empty array (`[]`), the props and state inside the effect will always have their initial values. While passing `[]` as the second argument is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, there are usually [better](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) [solutions](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) to avoid re-running effects too often. Also, don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem. | ||
| > | ||
| >If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (`[]`) as a second argument. This tells React that your effect doesn't depend on *any* values from props or state, so it never needs to re-run. This isn't handled as a special case -- it follows directly from how the inputs array always works. While passing `[]` is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, we suggest not making it a habit because it often leads to bugs, [as discussed above](#explanation-why-effects-run-on-each-update). Don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem. | ||
| >We provide an [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) ESLint rule as a part of the [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. |
There was a problem hiding this comment.
We recommend using the … as part of our …
content/docs/hooks-faq.md
Outdated
| ```js | ||
| useEffect(() => { | ||
| doSomething(); | ||
| }, []); // 🔴 This is not safe |
There was a problem hiding this comment.
Can you change this example so that it clearly comes from props and state? Since it is safe to call global functions.
Maybe by showing
function doSomething() {
console.log(someProp);
}
in component scope.
content/docs/hooks-faq.md
Outdated
|
|
||
| Let's see why this matters. | ||
|
|
||
| If you specify a [list of dependencies](/docs/hooks-reference.html#conditionally-firing-an-effect) as the last argument to `useEffect`, `useMemo`, `useCallback`, or `useImperativeHandle`, it must include all values used inside that participate in the React data flow. That includes props, state, or anything derived from them. |
There was a problem hiding this comment.
props, state, and anything derived from them.
Co-Authored-By: gaearon <dan.abramov@gmail.com>
Co-Authored-By: gaearon <dan.abramov@gmail.com>
Co-Authored-By: gaearon <dan.abramov@gmail.com>
Co-Authored-By: gaearon <dan.abramov@gmail.com>
Co-Authored-By: gaearon <dan.abramov@gmail.com>
|
I'll get this in for now. I'd love if someone can figure out a way to make it shorter but at least it's in the docs now. |
This addresses the common confusion points around the deps array and optimizing effects, and suggests concrete fixes. It might be too wordy but I figured it's probably worth including.
Open to edits.